﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FDEE.Model
{
    /// <summary>
    /// I梁的圆弧桥面
    /// </summary>
    public class TDeckSlabCurve : MemberBase
    {
        public eEndType EndA, EndB;
        public int BeamWA, BeamWB; // 两端盖梁凸出宽度，矩形盖梁为0；
        public int Width, WidthOuter;
        public int Thickness = 80;
        public int Span;
        public int Radius;
        public int TotalSpanLength;
        public int Cover = 40;
        public int NumHalfEJ, NumLink;
        public int IGirderDistA, IGirderDistB;
        public int EGirderDistA, EGirderDistB;


        /// <summary>
        /// 等宽曲线I梁桥面
        /// </summary>
        /// <param name="typeName"></param>
        /// <param name="pierNumber"></param>
        /// <param name="width">桥面总宽</param>
        /// <param name="widthOuter">桥面外宽</param>
        /// <param name="span">理论跨径</param>
        /// <param name="beamWA">小桩号侧盖梁宽</param>
        /// <param name="beamWB">大桩号侧盖梁宽</param>
        /// <param name="endA">小桩号桥面类型</param>
        /// <param name="endB">大桩号桥面类型</param>
        /// <param name="inGirderA">A侧内梁端距离</param>
        /// <param name="inGirderB">B侧内梁端距离</param>
        /// <param name="exGirderA">A侧外梁端距离</param>
        /// <param name="exGirderB">B侧外梁端距离</param>
        public TDeckSlabCurve(string typeName, string pierNumber,
            int width, int widthOuter, int span, int radius, int beamWA, int beamWB, eEndType endA, eEndType endB,
            int inGirderA, int inGirderB, int exGirderA, int exGirderB)
            : base(typeName, pierNumber)
        {
            this.Width = width;
            this.Radius = radius;
            this.WidthOuter = widthOuter;
            this.Span = span;
            this.BeamWA = beamWA;
            this.BeamWB = beamWB;
            this.EndA = endA;
            this.EndB = endB;
            this.IGirderDistA = inGirderA;
            this.IGirderDistB = inGirderB;
            this.EGirderDistA = exGirderA;
            this.EGirderDistB = exGirderB;

            double rad = (double)span / radius;

        }

        public override void SetConcreteClass()
        {
            ConcreteClass = eConcreteClass.C45;
        }

        public override void SetConcreteVolume()
        {
            ConcreteVolumn = Math.Round(Width * 1e-3 * TotalSpanLength * 1e-3 * Thickness * 1e-3, 3, MidpointRounding.AwayFromZero);
        }

        public override void SetRebarList()
        {
            int Gap = 0;
            if (EndA == eEndType.ExpansionJoint)
            {
                Gap += 25;
            }
            if (EndB == eEndType.ExpansionJoint)
            {
                Gap += 25;
            }
            EXNumber ex = new EXNumber();
            #region N1
            int LapLength = 1100;
            var splN1 = GetSplice(Width, Cover, LapLength, 12000);

            int NumN1 = (Span - Cover * 2 - Gap) / 150 + 1;

            if (splN1[1] == 1)
            {
                RebarList.Add(new MARebarRecord(1, 1, "", eDB.DB16, splN1[0], NumN1, eShapeType.MA));
            }
            else if (splN1[1] == 2)
            {
                RebarList.Add(new MABRebarRecord(1, 1, "", eDB.DB16, splN1[0] - LapLength, LapLength, NumN1, eShapeType.MAB));
                RebarList.Add(new MABRebarRecord(1, 2, "", eDB.DB16, LapLength, splN1[2] - LapLength, NumN1, eShapeType.MAB));

            }
            else
            {
                RebarList.Add(new MABRebarRecord(1, 1, "", eDB.DB16, splN1[0] - LapLength, LapLength, NumN1, eShapeType.MAB));
                RebarList.Add(new MABCRebarRecord(1, 2, "", eDB.DB16, LapLength, 12000 - LapLength * 2, LapLength, (splN1[1] - 2) * NumN1, eShapeType.MABC));
                RebarList.Add(new MABRebarRecord(1, 3, "", eDB.DB16, LapLength, splN1[2] - LapLength, NumN1, eShapeType.MAB));
            }
            #endregion

            #region N2
            double rad = (double)Span / Radius;
            int NumN2 = (Width - 2 * Cover) / 150 + 1;
            List<int[]> N2Table = new List<int[]>();
            for (int i = 0; i < NumN2; i++)
            {
                int r0 = Radius - (Width - WidthOuter) + Cover + 150 * i;
                int ArcLength = (int)Math.Round(r0 * rad - Gap, 0, MidpointRounding.AwayFromZero);
                var SplR = GetSplice(ArcLength, Cover, 650, 12000);
                // Debug.Assert(SplR[0] == 12000);
                N2Table.Add(SplR);
            }
            Debug.Assert(N2Table[0][1] == N2Table.Last()[1]);
            int k = N2Table[0][1];
            if (k == 1)
            {
                EXNumber rangeA = new EXNumber();
                rangeA.exNumber["A"] = N2Table.Last()[2] - N2Table.First()[2];
                int Aaverage = (int)Math.Round((N2Table.Last()[2] + N2Table.First()[2]) * 0.5, 0, MidpointRounding.AwayFromZero);
                RebarList.Add(new MABRebarRecord(2, 1, "", eDB.DB12, Aaverage - 650, 650, NumN2, eShapeType.MAB, rangeA));

            }
            else if (k == 2)
            {
                RebarList.Add(new MABRebarRecord(2, 1, "", eDB.DB12, N2Table.First()[0] - 650, 650, NumN2, eShapeType.MAB));
                EXNumber rangeA = new EXNumber();
                rangeA.exNumber["B"] = N2Table.Last()[2] - N2Table.First()[2];
                int Aaverage = (int)Math.Round((N2Table.Last()[2] + N2Table.First()[2]) * 0.5, 0, MidpointRounding.AwayFromZero);
                RebarList.Add(new MABRebarRecord(2, 2, "", eDB.DB12, 650, Aaverage - 650, NumN2, eShapeType.MBA, rangeA));
            }
            else
            {
                RebarList.Add(new MABRebarRecord(2, 1, "", eDB.DB12, N2Table.First()[0] - 650, 650, NumN2, eShapeType.MAB));
                RebarList.Add(new MABCRebarRecord(2, 2, "", eDB.DB12, 650, 12000 - 650 * 2, 650, NumN2 * (N2Table.First()[1] - 2), eShapeType.MABC));
                EXNumber rangeA = new EXNumber();
                rangeA.exNumber["B"] = N2Table.Last()[2] - N2Table.First()[2];
                int Aaverage = (int)Math.Round((N2Table.Last()[2] + N2Table.First()[2]) * 0.5, 0, MidpointRounding.AwayFromZero);
                RebarList.Add(new MABRebarRecord(2, 3, "", eDB.DB12, 650, Aaverage - 650, NumN2, eShapeType.MBA, rangeA));
            }


            ;
            #endregion

            #region N3
            #endregion

            #region N4
            #endregion

            #region N5
            #endregion

            RebarList.Sort();
        }

        /// <summary>
        /// 极坐标转笛卡尔坐标
        /// </summary>
        /// <param name="rad"></param>
        /// <param name="rho"></param>
        /// <returns></returns>
        double[] PT2XY(double rad, double rho)
        {
            return new double[] { rho * Math.Cos(rad), rho * Math.Sin(rad) };
        }

        /// <summary>
        /// 两点坐标求ABC
        /// </summary>
        /// <param name="x1"></param>
        /// <param name="y1"></param>
        /// <param name="x2"></param>
        /// <param name="y2"></param>
        /// <returns></returns>
        double[] ABC(double x1, double y1, double x2, double y2)
        {
            return new double[] { y2 - y1, x1 - x2, x2 * y1 - x1 * y2 };
        }



        int[] GetSplice(int L, int cover, int lap, int tryL1)
        {
            int Lr;
            int L1 = tryL1;
            int StandardLen = 12000;
            int LengthRaw = L - cover * 2;
            int n;
            if (LengthRaw <= StandardLen)
            {
                Lr = LengthRaw;
                n = 1;
                return new int[] { Lr, n, Lr };
            }
            else
            {
                // 需要切分

                int m = (LengthRaw - (L1 - lap / 2)) / (StandardLen - lap);
                Lr = LengthRaw - (L1 - lap / 2) - (StandardLen - lap) * m + lap / 2;
                if (Lr < 3 * lap)
                {
                    if (L1 > 6000)
                    {
                        return GetSplice(L, cover, lap, L1 - 3000);
                    }
                    else
                    {
                        throw new Exception("无法配置桥面纵筋：切分不合理");
                    }

                }
                n = m + 2;
                return new int[] { L1, n, Lr };
            }

        }
    }
}
